﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV.Structure;
using Emgu.CV;
using FaceRecognition.Models;

namespace FaceRecognition.View
{
    enum Emos
    {
        Happy = 0, Sad, Normal, Upnormal, Main
    }

    public partial class Form_Training : Form
    {
        private Controller_Class objController;
        private Face_Detection faceDetectObject1;
        private int picHeight, picWidth;
        private Image imgDefault;
        int userID;
        int secondsAllowed = 2000;
        Image[] imgs;
        int noPics = 4;
        int[] buttonClicked = { 0, 0, 0, 0 };
        Button[] buttons;
        PictureBox[] pictureboxes;
        int timePassed = 0;//timer interval =100 ms
        
        public Form_Training(int id)
        {
            this.userID = id;
            this.imgs = new Image[5];
            this.faceDetectObject1 = new Face_Detection();
            this.objController = new Controller_Class();
            this.InitializeComponent();
            this.buttons = new Button[4];
            this.pictureboxes = new PictureBox[4];
            this.buttons[0] = this.button_happy;
            this.buttons[1] = this.button_sad;
            this.buttons[2] = this.button_normal;
            this.buttons[3] = this.button_upnormal;
            this.pictureboxes[0] = this.pictureBox_Happy;
            this.pictureboxes[1] = this.pictureBox_Sad;
            this.pictureboxes[2] = this.pictureBox_Normal;
            this.pictureboxes[3] = this.pictureBox_Upnormal;
            //   ={button_happy,button_sad,button_normal,button_upnormal};
            this.picHeight = 128;
            this.picWidth = 128;

            try
            {
                this.imgDefault = this.faceDetectObject1.ResizeImage(Image.FromFile("..//admin.PNG"), new Size(this.picHeight, this.picWidth));
            }
            catch
            {
                MessageBox.Show("File not found  ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            for (int i = 0; i < this.noPics; i++)
            {
                this.imgs[i] = this.imgDefault;
            }

            this.pictureBox_Happy.Image = this.imgs[(int)Emos.Happy];
            this.pictureBox_Sad.Image = this.imgs[(int)Emos.Sad];
            this.pictureBox_Normal.Image = this.imgs[(int)Emos.Normal];
            this.pictureBox_Upnormal.Image = this.imgs[(int)Emos.Upnormal];
            this.pictureBox_main.Image = this.imgs[(int)Emos.Main];
        }

        private void Timer_camera_Tick(object sender, EventArgs e)
        {
            ///////////////////////////////////////////////////
            this.timePassed += timer_camera.Interval;
            this.label_time.Text = string.Empty + ((int)(this.secondsAllowed - this.timePassed) / 1000);
            ////////////////////////////////////////////////////
            Image<Bgr, byte> displayed_frame = null;
            this.faceDetectObject1.Detect_Face(this.faceDetectObject1.Capture_Frame(), ref displayed_frame);
            pictureBox_main.Image = displayed_frame.ToBitmap();

            this.Set_Images();
            if (this.timePassed > this.secondsAllowed)
            {
                timer_camera.Enabled = false;
                this.Set_Images();
                this.Time_Ended();
            }
        }

        private void Set_PictureBox(int no_pic)
        {
            if (this.buttonClicked[no_pic] == 1)
            {
                if (!timer_camera.Enabled && this.Check_Image_Default(this.imgs[no_pic]))
                {
                    MessageBox.Show("We couldn't take the Picture  ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (this.Check_Image_Default(this.imgs[no_pic]))
                {
                    //try catch
                    this.imgs[no_pic] = this.faceDetectObject1.Get_User_Face(new Size(this.picHeight, this.picWidth));
                    if (this.imgs[no_pic] == null)
                    {
                        this.imgs[no_pic] = this.imgDefault;
                    }
                    else
                    {
                        this.Time_Ended();

                    }
                    this.pictureboxes[no_pic].Image = this.faceDetectObject1.ResizeImage(this.imgs[no_pic], new Size(this.picHeight, this.picWidth));
                }
            }
        }

        private void Set_Images()
        {
            this.Set_PictureBox((int)Emos.Happy);
            this.Set_PictureBox((int)Emos.Sad);
            this.Set_PictureBox((int)Emos.Normal);
            this.Set_PictureBox((int)Emos.Upnormal);
        }

        private void Time_Ended()
        {
            this.timePassed = 0;
            this.label_time.Text = "" + this.timePassed;
            timer_camera.Stop();
            pictureBox_main.Image = this.imgDefault;
            
            for (int i = 0; i < this.noPics; i++)
            {
                this.buttonClicked[i] = 0;
            }

            for (int j = 0; j < this.noPics; j++)
            {
                this.buttons[j].Enabled = true;
            }
        }

        private bool Check_Image_Default(Image img)
        {
            if (img == this.imgDefault)
            {
                return true;
            }

            return false;
        }

        private void Button_happy_Click(object sender, EventArgs e)
        {
            this.Capture_OncePerTime((int)Emos.Happy);
        }

        private void Button_sad_Click(object sender, EventArgs e)
        {
            this.Capture_OncePerTime((int)Emos.Sad);
        }

        private void Button_normal_Click(object sender, EventArgs e)
        {
            this.Capture_OncePerTime((int)Emos.Normal);
        }

        private void Button_upnormal_Click(object sender, EventArgs e)
        {
            this.Capture_OncePerTime((int)Emos.Upnormal);
        }

        private void Capture_OncePerTime(int num_image)
        {
            this.buttonClicked[num_image] = 1;

            for (int j = 0; j < this.noPics; j++)
            {
                if (j == num_image)
                {
                    continue;
                }

                this.buttons[j].Enabled = false;
            }
            // MessageBox.Show("There is another operation wait till it fininshed ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            if (timer_camera.Enabled == false)
            {
                timer_camera.Start();
                timer_camera.Enabled = true;
            }

            this.imgs[num_image] = this.imgDefault;
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            this.faceDetectObject1.Close_Cam();
            this.Dispose();
            if (e.CloseReason == CloseReason.WindowsShutDown)
            {
                return;
            }

            // Confirm user wants to close
            //switch (MessageBox.Show(this, "Are you sure you want to close?", "Closing", MessageBoxButtons.YesNo))
            //{
            //    case DialogResult.No:
            //        e.Cancel = true;
            //        break;
            //    default:
            //        break;
            //}
        }

        private void Button_End_Click(object sender, EventArgs e)
        {
            this.faceDetectObject1.Close_Cam();
            try
            {
                this.objController.User.delete_user_info(this.userID);
            }
            catch
            {
                MessageBox.Show("Database Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            this.Dispose();
        }

        private void Button_add_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < this.noPics; i++)
            {
                if (this.Check_Image_Default(this.imgs[i]))
                {
                    MessageBox.Show("Make sure that you captured all the pictures ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            int id = this.userID;
            Face_Recognition obj_Face_Recognition = new Face_Recognition();

            string str;
            double[] arr_of_features;

//string buffer;// = new StringBuilder();
            try
            {
                for (int i = 0; i < this.noPics; i++)
                {
                    arr_of_features = obj_Face_Recognition.Extract_Features(ImageOperations.Convert_Image(this.imgs[i]));
                //    buffer ="";
                //    for (int a = 0; a < arr_of_features.Length; a++)
                //    {
                //        if (a != 0)
                //        {
                //            buffer+=",";
                //        }

                //        buffer+=((int)arr_of_features[a]).ToString();
                //    }

                //    str = buffer;
                   str= String.Join(",", arr_of_features.Select(p => p.ToString()).ToArray());
                    this.objController.Train.insert_Train_feature(id,str);
                }
            }
            catch
            {
                MessageBox.Show("Database Error ", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            MessageBox.Show("You are successfully added", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.Close();
            //save all images to database 
        }
    }
}
